Skip to content

Allow Table and Column name expressions to return SqlIdentifier #2077

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

serezakorotaev
Copy link
Contributor

By #1524

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jul 2, 2025
*/
class BasicRelationalPersistentEntity<T> extends BasicPersistentEntity<T, RelationalPersistentProperty>
implements RelationalPersistentEntity<T> {

private static final SpelExpressionParser PARSER = new SpelExpressionParser();

private final Lazy<SqlIdentifier> tableName;
private final @Nullable Expression tableNameExpression;
private final Lazy<SqlIdentifier> tableNameExpression;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's not what was meant here. We should remain with Expression (or switch to ValueExpression).

It was rather meant that a Expression (respective ValueExpression) should be able to return an SqlIdentifier and not be forced to return a String (as it is done now).

We also want to evaluate the expression each time we obtain names and we don't want to introduce caching.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry but perhaps I don't understand correctly. I see that ExpressionEvaluator returns String from Expression. Do you mean about it that no it is forced to return a String and should be able to return an SqlIdentifier? Like this
String result = expression.getValue(provider.getEvaluationContext(null), String.class);

Roughly, here we need to return SqlIdentifier, right?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ExpressionEvaluator should return a SqlIdentifier. This is a package-protected class and we're free to change its signature.

I suggest renaming it to SqlIdentifierExpressionEvaluator and not force a String type during expression evaluation (expression.getValue(…)), but introspect the returned object.

If it is already a SqlIdentifier, then just return it as-is, otherwise, transform the value to String and apply SqlIdentifierSanitizer. Then, apply force-quoting as per isForceQuote() of the calling code.

Does that help or did that increase confusion?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, thanks, it's clear! In first time I thought about something like this (not so detailed) but I was scary and not sure to change ExpressionEvaluator, sorry....
I'll do it a little bit later

@serezakorotaev
Copy link
Contributor Author

Hi! I've pushed changes. But I have a few questions just interesting for understanding.

  1. BasicRelationalPersistentProperty has sqlIdentifierExpressionEvaluator but it isn't set due to constructor as in BasicRelationalPersistentEntity. I see that it could be set like applyDefaults in RelationalMappingContext. Is it because BasicJdbcPersistentProperty is in jdbc package and we can't show it like a public?

  2. What is the difference between DefaultSqlIdentifier and DerivedSqlIdentifier? As I see it's the same but only there are in different packages. It's probably just now, and for future changes, it would be like a standard and specific strategy.

@mp911de mp911de added type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged labels Jul 16, 2025
@mp911de
Copy link
Member

mp911de commented Jul 16, 2025

Thanks a lot. To your questions:

  1. BasicRelationalPersistentProperty is a public type and therefore, we're limited in terms of changing constructors. Also, SqlIdentifierExpressionEvaluator is a type with package-private visibility and therefore, we cannot use it in a public constructor. BasicRelationalPersistentEntity is a package-private type so we can freely update its constructor and do not risk exposing an argument type that cannot be accessed by callers outside the package.
  2. It's mostly a package-visibility aspect but also, derived identifiers are subject to letter-casing normalization to align with database defaults when using derived naming (see IdentifierProcessing.standardizeLetterCase and DerivedSqlIdentifier.toSql(…)).

@serezakorotaev
Copy link
Contributor Author

Okay, thank you so much for answers!

mp911de pushed a commit that referenced this pull request Jul 16, 2025
Signed-off-by: Sergey Korotaev <[email protected]>
Closes #1524
Original pull request: #2077
mp911de added a commit that referenced this pull request Jul 16, 2025
Switch to value expressions to allow property-placeholder usage. Add tests. Add missing support for MappedCollection.idColumn() expressions.

See #1524
Original pull request: #2077
@mp911de mp911de added this to the 4.0 M4 (2025.1.0) milestone Jul 16, 2025
@mp911de
Copy link
Member

mp911de commented Jul 16, 2025

Thank you for your contribution. That's merged and polished now. Please mind providing tests the next time you want to contribute.

@mp911de mp911de closed this Jul 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: enhancement A general enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants